#if !defined(glib_g3_tetramesh_h)
#define glib_g3_tetramesh_h

#include "vector.h"
#include "trimesh.h"
#include "../callback.h"

#include <vector>

namespace g3 {

struct tetra 
{
	int v[4];
	tetra() { }
	tetra(int v0, int v1, int v2, int v3)
		{ v[0] = v0; v[1] = v1; v[2] = v2; v[3] = v3; }
	bool operator == (const tetra & rhs) const
	{
		return v[0] == rhs.v[0] && v[1] == rhs.v[1] && v[2] == rhs.v[2] && v[3] == rhs.v[3];
	}
	bool operator != (const tetra & rhs) const
	{
		return !operator == (rhs);
	}
};

inline std::ostream & operator << (std::ostream & out, const tetra & t)
{
	return out << t.v[0] << ' ' << t.v[1] << ' ' << t.v[2] << ' ' << t.v[3];
}

struct tetramesh
{
	std::vector<g3::vector>		coords; 
	std::vector<edge>			edges;
	std::vector<face>			surface;
	std::vector<tetra>			volume;

	void clear()
	{
		coords.clear();
		edges.clear();
		surface.clear();
		volume.clear();
	}

	void swap(tetramesh & rhs)
	{
		coords.swap(rhs.coords);
		edges.swap(rhs.edges);
		surface.swap(rhs.surface);
		volume.swap(rhs.volume);
	}
};

bool compute_surface(const tetramesh &, std::vector<face> &, glib::progress_callback * = 0);
void surface_to_trimesh(const tetramesh &, const std::vector<face> &, trimesh &, std::vector<int> * = 0);
bool compute_surface(const tetramesh &, trimesh &, std::vector<int> * = 0, glib::progress_callback * = 0);

} // g3

#endif // glib_g3_tetramesh_h
